const { signAccessToken, signRefreshToken, verifyRefreshToken } = require("../utils/tokens");
const asyncHandler = require("../utils/asyncHandler");
const RefreshToken = require("../models/RefreshToken");
const User = require("../models/User");
const { success, error } = require("../utils/response");

// 注册
exports.register = asyncHandler(async (req, res) => {
    const { username, email, password } = req.body;
    const exists = (await User.exists({ username })) || (await User.exists({ email }));
    if (exists)
        return error(res, '用户名或邮箱已存在');

    const user = await User.create({ username, email, password });
    return success(res, user)
});

// 登录
exports.login = asyncHandler(async (req, res) => {
    const { emailOrUsername, password } = req.body;
    const user = await User.findOne({
        $or: [{ email: emailOrUsername }, { username: emailOrUsername }],
    }).select("+password");

    if (!user)
        return error(res, '账号或密码错误');

    const ok = await user.comparePassword(password);
    if (!ok)
        return error(res, '账号或密码错误');

    const accessToken = signAccessToken({ sub: user._id, role: user.role });
    const refreshToken = signRefreshToken({ sub: user._id });

    // 保存刷新令牌以支持注销与吊销
    const payload = require("jsonwebtoken").decode(refreshToken);
    await RefreshToken.create({
        user: user._id,
        token: refreshToken,
        expiresAt: new Date(payload.exp * 1000),
    });
    const data = {
        accessToken,
        refreshToken,
        user: user,
    }

    return success(res, data, '登录成功')
});

// 刷新访问令牌
exports.refresh = asyncHandler(async (req, res) => {
    const { refreshToken } = req.body;
    if (!refreshToken)
        return error(res, '缺少刷新令牌');

    // 检查令牌是否在数据库中且未吊销
    const record = await RefreshToken.findOne({ token: refreshToken, revoked: false });
    if (!record)
        return error(res, '刷新令牌无效');

    const payload = verifyRefreshToken(refreshToken);
    const user = await User.findById(payload.sub);
    if (!user)
        return error(res, '用户不存在');

    const newAccess = signAccessToken({ sub: user._id, role: user.role });
    return success(res, { accessToken: newAccess })
});

// 注销（吊销刷新令牌）
exports.logout = asyncHandler(async (req, res) => {
    const { refreshToken } = req.body;
    if (refreshToken) {
        await RefreshToken.updateOne({ token: refreshToken }, { $set: { revoked: true } });
    }
    return success(res, null, '已注销')
});

// 获取当前用户
exports.me = asyncHandler(async (req, res) => {
    return success(res, { user: req.user })
});
